// 联合类型

//例如我们的手机号通常是13XXXXXXX 为数字类型 这时候产品说需要支持座机
//所以我们就可以使用联合类型支持座机字符串
let myPhone2: number | string = '010-820'

//这样写是会报错的应为我们的联合类型只有数字和字符串并没有布尔值
// let myPhone3333: number | string  = true

// /字符串字面量类型 => 使用枚举
type Easing = 'ease-in' | 'ease-out' | 'ease-in-out'

let ssss = 'ease-in'

// 只能赋值字面量中选项
let key888: Easing = 'ease-in'

if (key888 === 'ease-in') {
}

function checkKey88(pa: Easing) {
  if (pa === 'ease-in') {
  }

  if (pa === 'ease-out') {
  }
}

// type Easing = "ease-in" | "ease-out" | "ease-in-out";

const enum EasingEnum {
  EASE_IN = 'ease-in',
  EASE_OUT = 'ease-out',
  EASE_IN_OUT = 'ease-in-out',
}

const key99: EasingEnum = EasingEnum.EASE_IN // const key99 = "文江宜"

// const key99 = "ease-in"  // const key99 = "文江宜"

switch (checkKey889(EasingEnum.EASE_IN)) {
  case EasingEnum.EASE_IN_OUT: //类型“EasingEnum.EASE_IN_OUT”不可与类型“EasingEnum.EASE_IN”进行比较
    break
  case EasingEnum.EASE_IN: //类型“EasingEnum.EASE_IN_OUT”不可与类型“EasingEnum.EASE_IN”进行比较
    break

  default:
    break
}

// type:EasingEnum  = "文江宜" | "崔梦娇"

function checkKey889(pa: EasingEnum): EasingEnum {
  return pa
}

// class UIElement {
//     animate(dx: number, dy: number, easing: Easing) {
//         if (easing === "ease-in") {
//             // ...
//         }
//         else if (easing === "ease-out") {
//         }
//         else if (easing === "ease-in-out") {
//         }
//         else {
//             // error! should not pass null or undefined.
//         }
//     }
// }

// let button = new UIElement();
// button.animate(0, 0, "ease-in");
// button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here

interface People {
  age: number | string
  height: number
}
interface Man {
  sex: string
  age: string | number
}
// 交叉类型
const xiaoman = (man: People & Man) => {
  console.log(man.age)
  console.log(man.height)
  console.log(man.sex)
}
xiaoman({ age: 18, height: 180, sex: 'male' })

interface People0000 {
  age: number
  height: number
}
interface People0000 {
  sex: string
}
const xiaoman444 = (man: People0000) => {
  console.log(man.age)
  console.log(man.height)
  console.log(man.sex)
}
xiaoman({ age: 18, height: 180, sex: 'male' })

interface People333 {
  age: number
  height: number
}
interface Man33333 {
  sex: string
}

// 联合类型使用
const xiaoman33333 = (man: People333 | Man33333) => {
  console.log((man as People333).age)
  console.log((man as People333).height)
  console.log((man as Man33333).sex)

  console.log((<People333>man).age)
  console.log((<People333>man).height)
  console.log((<Man33333>man).sex)
}
xiaoman({ age: 18, height: 180, sex: 'male' })

const conObj = {
  name: 'zhichao',
}
conObj.name = 'jiangyi'

let letObj = {
  name: 'zhichao',
} as const

// letObj = 'sdf'
// letObj.name = 'dsf'

function toBoolean(something: any): boolean {
  return something as boolean
}

toBoolean(1)
// 返回值为 1
//

type Config = {
  apiEndpoint: string
  timeout: number
}

function updateConfig<K extends keyof Config>(key: K, value: Config[K]) {
  // key 必须是 Config 类型中的一个键
  // value 的类型必须与 Config[key] 的类型匹配
}

updateConfig('apiEndpoint', 'https://api.example.com') // 合法
// updateConfig("timeout", "1000ms"); // 错误: 类型 "string" 不能赋值给类型 "number"

const settings = {
  theme: 'dark',
  version: '1.0',
  useCache: true,
}

type SettingsKeys = keyof typeof settings // "theme" | "version" | "useCache"

function updateSetting(
  key: SettingsKeys,
  value: (typeof settings)[SettingsKeys]
) {
  // 更新设置的逻辑
}

namespace ss {
  type UserRole = 'admin' | 'user' | 'guest'

  type Permissions = {
    [role in UserRole]: string[]
  }

  const permissions: Permissions = {
    admin: ['create', 'edit', 'delete'],
    user: ['edit'],
    guest: [],
  }

  function getPermissions(role: keyof Permissions): string[] {
    return permissions[role]
  }

  class Bird {
    fly() {
      console.log('Flying...')
    }
  }

  class Fish {
    swim() {
      console.log('Swimming...')
    }
  }

  function move(animal: Bird | Fish) {


    if (animal instanceof Bird) {
      animal.fly() // TypeScript 知道 `animal` 是 `Bird`
    } else if (animal instanceof Fish) {
      animal.swim() // TypeScript 知道 `animal` 是 `Fish`
    }
  }
}
